//#define NFCONF ((volatile unsigned short*)0x4E000000)
//#define NFCONT ((volatile unsigned short*)0x4E000004)
//#define NFCMMD ((volatile unsigned char*)0x4E000008)
////#define NFDATA ((volatile unsigned char*)0x4E000010)
//#define NFADDR ((volatile unsigned char*)0x4E00000C)
//#define NFSTAT ((volatile unsigned char*)0x4E000020)
//
//#define PAGE_SIZE 2048











//Nand Flash
#define rNFCONF     (*(volatile unsigned *)0x4E000000)      //NAND Flash configuration
#define rNFCONT     (*(volatile unsigned *)0x4E000004)      //NAND Flash control
#define rNFCMD      (*(volatile unsigned *)0x4E000008)      //NAND Flash command
#define rNFADDR     (*(volatile unsigned *)0x4E00000C)      //NAND Flash address
#define rNFDATA     (*(volatile unsigned *)0x4E000010)      //NAND Flash data
#define rNFDATA8    (*(volatile unsigned char *)0x4E000010)     //NAND Flash data
//#define NFDATA      (0x4E000010)      //NAND Flash data address
#define rNFMECCD0   (*(volatile unsigned *)0x4E000014)      //NAND Flash ECC for Main Area
#define rNFMECCD1   (*(volatile unsigned *)0x4E000018)
#define rNFSECCD    (*(volatile unsigned *)0x4E00001C)      //NAND Flash ECC for Spare Area
#define rNFSTAT     (*(volatile unsigned *)0x4E000020)      //NAND Flash operation status
#define rNFESTAT0   (*(volatile unsigned *)0x4E000024)
#define rNFESTAT1   (*(volatile unsigned *)0x4E000028)
#define rNFMECC0    (*(volatile unsigned *)0x4E00002C)
#define rNFMECC1    (*(volatile unsigned *)0x4E000030)
#define rNFSECC     (*(volatile unsigned *)0x4E000034)
#define rNFSBLK     (*(volatile unsigned *)0x4E000038)      //NAND Flash Start block address
#define rNFEBLK     (*(volatile unsigned *)0x4E00003C)      //NAND Flash End block address



#define NUM_BLOCKS          0x1000  //  64 MB Smartmedia card.
#define SECTOR_SIZE         512
#define SPARE_SIZE          16
#define PAGES_PER_BLOCK         32

//  For flash chip that is bigger than 32 MB, we need to have 4 step address
//
#define NFCONF_INIT         0xF830  // 512-byte 4 Step Address
#define NEED_EXT_ADDR           1
//#define NFCONF_INIT           0xA830  // 256-byte 4 Step Address
//#define NEED_EXT_ADDR         0

//#define NFCONF_INIT           0xF840

//  NAND Flash Command. This appears to be generic across all NAND flash chips
#define CMD_READ            0x00    //  Read
#define CMD_READ1           0x01    //  Read1
#define CMD_READ2           0x50    //  Read2
#define CMD_READ3           0x30    //  Read3
#define CMD_READID          0x90    //  ReadID
#define CMD_WRITE1          0x80    //  Write phase 1
#define CMD_WRITE2          0x10    //  Write phase 2
#define CMD_ERASE1          0x60    //  Erase phase 1
#define CMD_ERASE2          0xd0    //  Erase phase 2
#define CMD_STATUS          0x70    //  Status read
#define CMD_RESET           0xff    //  Reset

//  Status bit pattern
#define STATUS_READY            0x40    //  Ready
#define STATUS_ERROR            0x01    //  Error

//  Status bit pattern
#define STATUS_READY            0x40
#define STATUS_ERROR            0x01

#define NF_CMD(cmd)         {rNFCMD  = (cmd); }
#define NF_ADDR(addr)           {rNFADDR = (addr); }
#define NF_nFCE_L()         {rNFCONT &= ~(1<<1); }
#define NF_nFCE_H()         {rNFCONT |= (1<<1); }
#define NF_RSTECC()         {rNFCONT |= (1<<4); }
#define NF_RDMECC()         (rNFMECC0 )
#define NF_RDSECC()         (rNFSECC )
#define NF_RDDATA()         (rNFDATA)
#define NF_RDDATA8()            (rNFDATA8)
#define NF_WRDATA(data)         {rNFDATA = (data); }
#define NF_WAITRB()         {while(!(rNFSTAT&(1<<0)));}
#define NF_CLEAR_RB()           {rNFSTAT |= (1<<2); }
#define NF_DETECT_RB()          {while(!(rNFSTAT&(1<<2)));}
#define NF_MECC_UnLock()        {rNFCONT &= ~(1<<5); }
#define NF_MECC_Lock()          {rNFCONT |= (1<<5); }
#define NF_SECC_UnLock()        {rNFCONT &= ~(1<<6); }
#define NF_SECC_Lock()          {rNFCONT |= (1<<6); }

#define RdNFDat8()          (rNFDATA8)  //byte access
#define RdNFDat()           RdNFDat8()  //for 8 bit nand flash, use byte access
#define WrNFDat8(dat)           (rNFDATA8 = (dat))  //byte access
#define WrNFDat(dat)            WrNFDat8()  //for 8 bit nand flash, use byte access

#define pNFCONF             rNFCONF
#define pNFCMD              rNFCMD
#define pNFADDR             rNFADDR
#define pNFDATA             rNFDATA
#define pNFSTAT             rNFSTAT
#define pNFECC              rNFECC0

#define NF_CE_L()           NF_nFCE_L()
#define NF_CE_H()           NF_nFCE_H()
#define NF_DATA_R()         rNFDATA
#define NF_ECC()            rNFECC0

// HCLK=100Mhz
#define TACLS               1   // 1-clk(0ns)
#define TWRPH0              4   // 3-clk(25ns)
#define TWRPH1              0   // 1-clk(10ns)  //TACLS+TWRPH0+TWRPH1>=50ns



static void rNF_Reset()
{
    NF_CE_L();//enable chip select                      {(*(volatile unsigned *)0x4E000004) &= ~(1<<1); }
    NF_CLEAR_RB();//set as "transition occured".        {(*(volatile unsigned *)0x4E000020) |= (1<<2); }
    NF_CMD(CMD_RESET);//{(*(volatile unsigned *)0x4E000008)  = (0xff); }
    NF_DETECT_RB();//while(st.bit2==0),so "transition occured" mean's not busy.         {while(!((*(volatile unsigned *)0x4E000020)&(1<<2)));}
    NF_CE_H();//disable chip select.                                                    {(*(volatile unsigned *)0x4E000004) |= (1<<1); }
}


void rNF_Init(void)
{
    //rNFCONF |= (TACLS << 12) | (TWRPH0 << 8) | (TWRPH1 << 4) | (0 << 0);
    rNFCONF |= (TACLS << 12); //1<<12
    rNFCONF |= (TWRPH0 << 8); //4<<8

    rNFCONT = (0 << 13) | (0 << 12) | (0 << 10) | (0 << 9) | (0 << 8) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 1) | (1 << 0);//0x63, after setted you may see 0x62..
    rNF_Reset();
}

//large page:2k,2048 byte
void rLB_ReadPage(unsigned int page_no, unsigned char * to)
{
    unsigned int i;

    rNF_Reset();

    //  Enable the chip
    NF_nFCE_L();//{(*(volatile unsigned *)0x4E000004) &= ~(1<<1); }
    NF_CLEAR_RB();//{(*(volatile unsigned *)0x4E000020) |= (1<<2); }

    // Issue Read command
    NF_CMD(CMD_READ);//{(*(volatile unsigned *)0x4E000008)  = (0x00); }

    //  Set up address
    NF_ADDR(0x00);//{(*(volatile unsigned *)0x4E00000C) = (0x00); }
    NF_ADDR(0x00);//{(*(volatile unsigned *)0x4E00000C) = (0x00); }
    NF_ADDR((page_no) & 0xff);
    NF_ADDR((page_no >> 8) & 0xff);
    NF_ADDR((page_no >> 16) & 0xff);

    NF_CMD(CMD_READ3);//{(*(volatile unsigned *)0x4E000008)  = (0x30); }

    NF_DETECT_RB();     // wait tR(max 12us) {while(!((*(volatile unsigned *)0x4E000020)&(1<<2)));}

    for (i = 0; i < 2048; i++)
    {
        to[i] =  NF_RDDATA8();
    }

    NF_nFCE_H();

}







